const log4js      = require('../../data/log');
const logger      = log4js.getLogger('info');
const server      = require('../../sip/server');
const constants   = require('../../data/constants');
const channelCtrl    = require('./channel');
const channelModel   = require('../../model/channel');
const mediaserverModel = require('../../model/mediaserver');
const httpUtils   = require('../../utils/httpUtils');
const mediaUtils = require('./mediautils');

//与 ZLMediaKit 交互
const MediaCtrlModule={
    // 记录已使用的端口号
    ports:{},
    // 没有首页
    index:function(req,res){
        res.send('NOT IMPLEMENTED: index');
    },
    // 读取目标媒体服务器配置信息
    getServerConfig(req,res){
        let url = `http://${req.query.host}:${req.query.port}/index/api/getServerConfig?secret=${req.query.secret}`;
        httpUtils.get(url, '').then(tmp => {
            if(tmp.code === 0){
                tmp.code = constants.httpCode.OK.code
                tmp.message = constants.httpCode.OK.message
            }else{
                tmp.code = constants.httpCode.ILLEGAL_TOKEN.code;
                tmp.message = constants.httpCode.ILLEGAL_TOKEN.message
            }
            res.send(tmp);
        })
    },
    // ZLMediaKit 找不到流的时候请求这个接口
    onStreamNotFound(req,res){
        res.send({'code':0,'msg':'success'});
    },
    onFlowReport(req,res){
        res.send({'code':0,'msg':'success'});
    },
    // ZLMediaKit 启动时调用这个接口
    onServerStarted(req,res){
        let serverId = req.body['general.mediaServerId'];
        constants.mediaservers[serverId] = req.body;
        res.send({'code':0, 'msg':'success'});
    },
    // 流没人观看时调用这个接口
    async onStreamNoneReader(req, res) {
        logger.info('onStreamNoneReader', req.body);
        /**
         {
    mediaServerId: '',
    app: 'rtp',
    schema: 'rtmp',
    stream: 'v_34020000001320000002_34020000001310000006',
    vhost: '__defaultVhost__'
    }
         */
        let stream = req.body.stream.split('_');

        await server.bye(stream[1], stream[2]);
        res.send({'code': 0, 'msg': 'success'});
    },
    // 播放节目
    async onPlay(req,res){
        let mediaServerId = req.body.mediaServerId;
        let stream_id = req.body.stream;

        if(!mediaServerId || !stream_id){
            res.send({'code':1, 'msg':'参数错误','param': req.body});
            return;
        }


        // 获取一个port
        try {
            const rtpRet = await MediaCtrlModule.openRtpServer({body: {stream_id: stream_id, media_server_id: mediaServerId}});
            logger.info(`[API] [media] mediaServierId=${mediaServerId} stream_id=${stream_id} onPlay被触发,准备请求媒体服务器打开rtp端口，返回:`,rtpRet);
            const res1 = rtpRet.res;
            const media_ip = rtpRet.media_ip;
            const intranet = rtpRet.intranet;
            logger.info(`[API] 请求rtp server,stream_id=${stream_id}，返回:`, rtpRet)
            // 发invite请求
            let stream = stream_id.split('_');
            let sendPort;
            if (res1.code === -300) {

                // 流已经存在，去查找一下
                const rows = await MediaCtrlModule.listRtpServer(mediaServerId);
                let port = 0;
                const rtpPorts = rows.data.find((item) => {
                    return item.stream_id === stream_id
                });
                logger.info(`mediaServierId=${mediaServerId} stream_id=${stream_id} 请求媒体服务器打开rtp端口时反馈流已存在,返回值:`,
                    res1,'intranet=', intranet,'listRtpServer列表', rows);
                if (rtpPorts) {
                    port = rtpPorts.port;
                }
                if (port > 0) {
                    sendPort = port;
                } else {
                    sendPort = null;
                    res.send({'code': 1, 'msg': '向媒体服务器申请rtp端口失败'});
                }
            } else {
                logger.info(`mediaServierId=${mediaServerId} stream_id=${stream_id} 请求媒体服务器打开rtp端口，新流准备分新端口`, res1, media_ip);
                sendPort = res1.port;
            }
            if(sendPort){
                const ret = await server.invite(media_ip, stream[1], stream[2], sendPort);
                logger.info(`mediaServierId=${mediaServerId} stream_id=${stream_id} port=${sendPort} 发送invite信令 返回值：`, ret);
                if (ret) {
                    res.send({'code': 0, 'msg': 'success'});
                } else {
                    res.send({'code': 1, 'msg': '发送invite信令失败'});
                }
            }else{
                logger.error(`mediaServierId=${mediaServerId} stream_id=${stream_id} 发送invite信令时没获取到rtp端口`);
            }
        }catch (e){
            res.send({'code': 1, 'msg': `发生异常:${e}`});
        }
    },

    /**
     * 播放hls时鉴权，这里暂时全设置为允许观看
     */
    onHttpAccess(req,res){
        res.send({
            'code':0,
            'err':'',
            path:req.body.path,
            second:600,
            mediaServerId:req.body.mediaServerId
        });
    },
    async onStreamChanged(req,res){
        let method = req.body.regist;
        // let serverId = req.body.mediaServerId;

        if(method && req.body.schema==='rtsp'){
            // 注册时顺便截图
            let stream = req.body.stream.split('_');
            if(!stream || stream.length<3 || !stream[1] || !stream[2]){
                logger.warn('截图，参数异常,stream=', stream);
                res.send({'code': 0, 'msg': 'success'});
            }else {
                let rtmp = await channelCtrl.calcMediaUrl(stream[1], stream[2], 'rtmp_snap');
                logger.info('截图', rtmp);

                mediaUtils.snap(rtmp, stream[1], stream[2]).then((ret) => {

                    channelModel.updateSnap(ret.toString(), stream[1], stream[2]).then(() => {
                        res.send({'code': 0, 'msg': 'success'});
                    }).catch(() => {
                        res.send({'code': 1, 'msg': '更新截图信息失败'});
                    })

                }).catch((err) => {
                    logger.error(err);
                });
            }
        }else{
            res.send({'code': 0, 'msg': 'success'});
        }
    },
    onPublish(req,res){
        res.send({'code': 0, 'msg': 'success'});
    },
    // 查询rtp列表
    rtpList(req,res){
        let serverId = req.query.media_server_id;
        MediaCtrlModule.listRtpServer(serverId).then((list) => {
            res.send(Object.assign(constants.httpCode.OK, {data:list}));
        }).catch((err)=>{
            res.send(Object.assign(constants.httpCode.ILLEGAL_PARAM, {data:err}));
        });
    },

    /**
     * 调用zlmediaKit的 /index/api/openRtpServer接口 ，用于打开一个rtp端口
     */
    openRtpServer(req){
        const me = MediaCtrlModule;
        return new Promise(async function(resolve, reject){
            const serverId = req.body.media_server_id;
            const streamId = req.body.stream_id;

            let host =await mediaserverModel.getInfoByServerId(serverId);
            logger.info('[API 主机列表]', serverId, host);
            let url = host.zlk_api_host + 'index/api/openRtpServer';
            // 选取一个空余端口号
            let max = host.rtp_max_port;
            let min = host.rtp_min_port;
            if(!me.ports.index) me.ports.index = min-2;

            let port;
            if (me.ports[streamId]) {
                port = me.ports[streamId];
            } else {
                me.ports.index += 2;
                port = me.ports.index;
                me.ports[streamId] = port;
            }
            if (port > max) {
                logger.error(`openRtpServer时,没有可用端口了 streamId=${streamId}`);
            } else {
                let param = `secret=${host.secret}&port=${port}&enable_tcp=1&stream_id=${streamId}`;

                httpUtils.get(url, param).then((res) => {
                    resolve({res: res, intranet: host.intranet,media_ip:host.media_ip});
                }).catch((e) => {
                    logger.error(`mediaServierId=${serverId} stream_id=${streamId} 请求媒体服务器 openRtsServer 出错, error=${e}`);
                    reject(e);
                });
            }
        });
    },


    /**
     * 释放所有rtp资源
     */
    resetRtpServer(serverId){
        MediaCtrlModule.listRtpServer(serverId).then(async (list)=>{
            console.info('print rtp server list', list);
            for(let i in list.data){
                let stream=list.data[i].stream_id;
                await MediaCtrlModule.closeRtpServer(serverId, stream);
            }
        }).catch((err) => {
            logger.error('释放rtp资源出错,检查媒体服务器是否正常。错误信息=', err);
        });
    },

    /**
     * 调用zlmediaKit的 /index/api/closeRtpServer
     **/
    async closeRtpServer (serverId, stream) {
        let host = await mediaserverModel.getInfoByServerId(serverId);
        let url = host.zlk_api_host + 'index/api/closeRtpServer';
        let param = "?secret=" + host.secret + "&port=0&enable_tcp=false&stream_id=" + stream;
        console.info('get host info', host, 'serverId', serverId, 'param=', param);
        httpUtils.get(url, param).then((res) => {
            logger.log(res);
        }).catch((e) => {
            logger.error(e);
        });
    },
    /**
     * 调用zlmediaKit的 /index/api/listRtpServer
     **/
    async listRtpServer(serverId){
        let host =await mediaserverModel.getInfoByServerId(serverId);

        if(host && host.zlk_api_host){
            let url = host.zlk_api_host + 'index/api/listRtpServer';
            let param ="?secret=" + host.secret;
            return httpUtils.get(url ,param);
        }else{
            logger.error("请打开网页设置媒体服务器地址。");
        }
    },

    async ping(serverId){
        let host =await mediaserverModel.getInfoByServerId(serverId);
        console.log('host',host);
        let url = host.zlk_api_host + 'index/api/listRtpServer';
        let param = "?secret=" + host.secret;
        return httpUtils.get(url, param);
    }
};

module.exports=MediaCtrlModule;
